// $codepro.audit.disable declareDefaultConstructors
// com.instantiations.assist.eclipse.analysis.deserializeabilitySecurity
package org.mysofts.eclipseman.launch;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.mysofts.eclipseman.Eclipse;
import org.mysofts.eclipseman.EclipseInstallations;
import org.mysofts.eclipseman.launch.util.AbstractLauncher;
import org.mysofts.eclipseman.util.MessageProvider;

/**
 * Executable qui liste les installations d'eclipse disponibles.
 * 
 * @author reda
 * 
 * @version $Revision: 1.0 $
 */
public final class EclipseList extends AbstractLauncher {
	/**
	 * Séparateur de lignes de la plate-forme.
	 */
	private static final String LINE_SEPARATOR = SystemUtils.LINE_SEPARATOR;

	// $codepro.audit.disable
	// declareDefaultConstructors
	/**
	 * Nom du script.
	 */
	public static final String SCRIPT_NAME = "eclipse-list";

	/**
	 * Option verbose.
	 */
	private Option oVerbose;
	/**
	 * detailled.
	 */
	private boolean detailled;
	/**
	 * filter.
	 */
	private boolean filter;
	/**
	 * filterString.
	 */
	private String filterString;
	/**
	 * eclipses.
	 */
	private final List<Eclipse> eclipses;

	/**
	 * Constructeur.
	 * 
	 * @param args
	 *            Arguments
	 */
	public EclipseList(final String[] args) {
		super(SCRIPT_NAME + " OPTIONS [FILTRE]", args);
		this.eclipses = new ArrayList<Eclipse>();
	}

	@Override
	protected void parseOptions(final CommandLine commandLine)
			throws ParseException {
		this.detailled = commandLine.hasOption(this.oVerbose.getOpt());
	}

	@Override
	protected void parseArguments(final String[] args) throws ParseException {
		this.filterString = StringUtils.EMPTY;
		if (1 == args.length) {
			this.filterString = args[0];
		} else if (args.length > 1) {
			throw new ParseException(MessageFormat.format(
					MessageProvider.get("logs").sub("launchers").sub("errors")
					.sub("argerror").value(), 1));
		}
		this.filter = !StringUtils.isBlank(this.filterString);
	}

	@Override
	protected void createOptions(final List<Option> optlist) {
		this.oVerbose = new Option(MessageProvider.get("opts").sub("list")
				.sub("verbose").sub("short").value(), MessageProvider
				.get("opts").sub("list").sub("verbose").sub("long").value(),
				false, MessageProvider.get("opts").sub("list").sub("verbose")
						.sub("description").value());

		optlist.add(oVerbose);
	}

	/**
	 * Filtre la liste des eclipses.
	 */
	private void dofilter() {
		List<Eclipse> all = Arrays.asList(EclipseInstallations.get()
				.getInstalledEclipses());
		if (!filter) {
			this.eclipses.addAll(all);
		} else {
			for (Eclipse eclipse : all) {
				if (StringUtils.containsIgnoreCase(eclipse.getName(),
						this.filterString)) {
					this.eclipses.add(eclipse);
				}
			}
		}
	}

	/**
	 * Affiche la liste.
	 */
	private void print() {
		final StringBuilder text = new StringBuilder(10 * eclipses.size());
		if (detailled) {
			for (Eclipse eclipse : eclipses) {
				text.append(eclipse.getName());
				text.append('\t');
				text.append(eclipse.getReleaseVersion());
				text.append(LINE_SEPARATOR);
			}
		} else {
			boolean first = true;
			for (Eclipse eclipse : eclipses) {
				if (!first) {
					text.append('\t');
				} else {
					first = false;
				}
				text.append(eclipse.getName());
			}
		}

		System.out.println(text.toString());
	}

	/**
	 * Main method.
	 * 
	 * @param args
	 *            Argument de ligne de commande.
	 */
	public static void main(final String[] args) {
		EclipseList obj = new EclipseList(args);
		obj.dofilter();
		obj.print();
	}

}
